package com.wish.finance.service.impl;

import com.wish.finance.entity.JrProduct;
import com.wish.finance.entity.JrSfLoan;
import com.wish.finance.entity.TCwPaymentPlan;
import com.wish.finance.entity.TSfContract;
import com.wish.finance.entity.vo.SearchSfLoanDetailMiniResponseDto;
import com.wish.finance.entity.vo.SearchSfLoanDetailRequestDto;
import com.wish.finance.entity.vo.SearchSfLoanDetailsResponseDto;
import com.wish.finance.entity.vo.SfContractDetailsResponseDTO;
import com.wish.finance.mapper.JrSfLoanMapper;
import com.wish.finance.service.IJrProductService;
import com.wish.finance.service.IJrSfLoanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wish.finance.service.ITCwPaymentPlanService;
import com.wish.finance.service.ITSfContractService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 收房贷申请信息 服务实现类
 * </p>
 *
 * @author xiaocui
 * @since 2022-04-06
 */
@Service
public class JrSfLoanServiceImpl extends ServiceImpl<JrSfLoanMapper, JrSfLoan> implements IJrSfLoanService {

    @Autowired
    private ITSfContractService sfContractService;

    @Autowired
    private ITCwPaymentPlanService cwPaymentPlanService;

    @Autowired
    private IJrProductService jrProductService;
    /*
        收房贷
     */
    @Override
    public SfContractDetailsResponseDTO getSfContract(Long sfContractId) {
        //根据合同id查询合同信息
        TSfContract tSfContract = sfContractService.getById(sfContractId);
        SfContractDetailsResponseDTO sfContractDetailsResponseDTO = new SfContractDetailsResponseDTO();
        //将相同属性赋值
        BeanUtils.copyProperties(tSfContract,sfContractDetailsResponseDTO);
        /*借款金额*/
        //查询收房分期
        Map<String, Object> param = new HashMap<>();
            //收房
            param.put("contract_type", 1);
            //合同ID
            param.put("contract_id", sfContractId);
            //收房付款单
            param.put("pay_type", 1);
            //未付款
            param.put("pay_state", 1);
            //普通账单
            param.put("bill_type", 3);
            //租金
            param.put("item_type", 3);
        List<TCwPaymentPlan> payList = cwPaymentPlanService.listByMap(param);
        BigDecimal balance = new BigDecimal("0.00");
        Date startDate = null;
        if (payList.size() > 0) {
            for (TCwPaymentPlan r : payList) {
                //应付金额总计
                balance = balance.add(r.getPaymentAmount()).setScale(2, BigDecimal.ROUND_HALF_UP);
                //第一次账单开始时间
                if (null == startDate) {
                    startDate = r.getPaymentDaysBegin();
                }
                //如果账单开始时间大于参数返回 1,则更新账单开始日期
                else if (1 == startDate.compareTo(r.getPaymentDaysBegin())) {
                    startDate = r.getPaymentDaysBegin();
                }
            }
        }
        //获取合同租约期限结束时间
        Date endDate = tSfContract.getLeaseEndTime();
        //将账单开始时间和结束时间赋值
        sfContractDetailsResponseDTO.setEndDate(endDate);
        sfContractDetailsResponseDTO.setStartDate(startDate);
        // 根据一段时间区间，按月份拆分成多个时间段
        List<KeyValueForDate> splitMonth = getSplitMonthForDate(startDate, endDate);
        //剩余合同期限
        if (splitMonth == null) {
            sfContractDetailsResponseDTO.setPeriods(0);
        } else {
            sfContractDetailsResponseDTO.setPeriods(splitMonth.size());
        }
        // 查询收房分期 - 付款计划（ 已付款）
        param.remove("pay_state");
        param.put("pay_state", 2);
        int count = cwPaymentPlanService.listByMap(param).size();
        // 计算 借款金额 期数
        if (count != 0) {
            //借款金额
            sfContractDetailsResponseDTO.setBalance(balance);
            //授信额
            sfContractDetailsResponseDTO.setSxBalance(balance);
        } else {
            //进行除法运算
            BigDecimal divide = balance.divide(BigDecimal.valueOf(splitMonth.size()), 2, BigDecimal.ROUND_HALF_UP);
            //进行减法运算
            balance = balance.subtract(divide).setScale(2, BigDecimal.ROUND_HALF_UP);
            //日历
            Calendar cl = Calendar.getInstance();
            //将账单开始时间转换为时间戳
            cl.setTime(sfContractDetailsResponseDTO.getStartDate());
            //加一个月
            cl.add(Calendar.MONTH, 1);
            sfContractDetailsResponseDTO.setStartDate(cl.getTime());
            //期数  不减1
            sfContractDetailsResponseDTO.setPeriods(splitMonth.size() - 1);
            //// 借款金额
            sfContractDetailsResponseDTO.setBalance(balance);
            // 授信额
            sfContractDetailsResponseDTO.setSxBalance(balance);
        }
        return sfContractDetailsResponseDTO;
    }

    @Override
    public List<JrProduct> searchProduct(int i) {
        return baseMapper.searchProduct(i);
    }



    /**
     * @deprecated  金融产品选择(其中一条)
     * @Date 2022/4/6 15:16
     **/
    @Override
    public JrProduct searchProductById(Long id) {
        return jrProductService.getById(id);
    }

    /**
     * 收房贷计算详情
     * @param sfContractId 收房ID
     * @param productId 金融产品ID
     * @return
     */
    @Override
    public SfContractDetailsResponseDTO getSfContractStagingCalculation(Long sfContractId, Long productId) {
        //获取收房合同信息
        TSfContract sfce = sfContractService.getById(sfContractId);
        SfContractDetailsResponseDTO sfdto = new SfContractDetailsResponseDTO();
        BeanUtils.copyProperties(sfce,sfdto);
        //查询收房分期
        Map<String, Object> param = new HashMap<>();
        //收房
        param.put("contract_type", 1);
        //合同ID
        param.put("contract_id", sfContractId);
        //收房付款单
        param.put("pay_type", 1);
        //未付款
        param.put("pay_state", 1);
        //普通账单
        param.put("bill_type", 3);
        //租金
        param.put("item_type", 3);
        List<TCwPaymentPlan> payList = cwPaymentPlanService.listByMap(param);
        //获取金融产品信息
        JrProduct jrProduct = jrProductService.getById(productId);
        //计算的授信额度
        BigDecimal decimal = new BigDecimal(100);
        BigDecimal divide = jrProduct.getCreditLine().divide(decimal, 2, BigDecimal.ROUND_HALF_UP);
        BigDecimal balance = new BigDecimal("0.00");
        if (payList.size() > 0) {
            for (TCwPaymentPlan pay : payList) {
                balance = balance.add(pay.getPaymentAmount()).setScale(2, BigDecimal.ROUND_HALF_UP);
            }
        }
        //获取期数
        int size = payList.size();
        //支付方式(押X付Y的Y）
        Integer paymentType = sfce.getPaymentType();
        //进行乘法运算
        BigDecimal period = BigDecimal.valueOf(size).multiply(BigDecimal.valueOf(paymentType)).setScale(2, BigDecimal.ROUND_HALF_UP);
        //期数
        sfdto.setPeriods(period.intValue());
        //总金额
        sfdto.setBalance(balance);
        // 授信总额
        BigDecimal sxBalance = sfdto.getBalance().multiply(divide).setScale(2, BigDecimal.ROUND_HALF_UP);
        sfdto.setSxBalance(sxBalance);
        return sfdto;
    }


    /**
     * @deprecated 收房贷 -------计算分期详情
     * @Date 2022/4/6 16:13
     **/
    @Override
    public SearchSfLoanDetailsResponseDto getSfLoanDetail(SearchSfLoanDetailRequestDto sfdto) {
        SearchSfLoanDetailsResponseDto dto = new SearchSfLoanDetailsResponseDto();
        List<SearchSfLoanDetailMiniResponseDto> spList = new ArrayList<SearchSfLoanDetailMiniResponseDto>();
        JrProduct product = jrProductService.getById(sfdto.getProductId());
        //授信率
        BigDecimal decimal = new BigDecimal(100);
        BigDecimal creditLine = product.getCreditLine().divide(decimal, 2, BigDecimal.ROUND_HALF_UP);
        //一次性服务费
        BigDecimal serviceFee = new BigDecimal(sfdto.getServiceFee()).divide(decimal, 4, BigDecimal.ROUND_HALF_UP);
        //利率
        BigDecimal rate = new BigDecimal(sfdto.getRate()).divide(decimal, 4, BigDecimal.ROUND_HALF_UP);
        //授信额合计  乘法运算
        BigDecimal sxBalance = sfdto.getBalance().multiply(creditLine).setScale(2, BigDecimal.ROUND_HALF_UP);
        //合同期数
        int sfperiods = sfdto.getPeriods().intValue();

        //服务费合计=   (借款金额*年一次性服务费 /12 * 期数 * 授信额)
        BigDecimal serCharge = sfdto.getBalance()
                //借款金额*年一次性服务费
                .multiply(serviceFee).setScale(2, BigDecimal.ROUND_HALF_UP)
                //  /12
                .divide(BigDecimal.valueOf(12),2,BigDecimal.ROUND_HALF_UP)
                //* 期数
                .multiply(BigDecimal.valueOf(sfperiods)).setScale(2, BigDecimal.ROUND_HALF_UP)
                //* 授信额
                .multiply(creditLine).setScale(2, BigDecimal.ROUND_HALF_UP);

        //计算 月租金  = 借款金额 / 期数
        BigDecimal month_RateAmount = sfdto.getBalance().divide(BigDecimal.valueOf(sfperiods), 2, BigDecimal.ROUND_HALF_UP);
        // 借款总额(应付租约合计 )   = 月租金 * 期数 * 授信率
        BigDecimal payAbleCount = month_RateAmount.multiply(BigDecimal.valueOf(sfperiods)).setScale(2, BigDecimal.ROUND_HALF_UP)
                .multiply(creditLine).setScale(2, BigDecimal.ROUND_HALF_UP);

        // 计算收房贷利息合计= 借款总金额* 利率/12  * 期数
        BigDecimal monthRateAmounts = payAbleCount
                //借款金额* 利率
                .multiply(rate).setScale(2, BigDecimal.ROUND_HALF_UP)
                //利率/12
                .divide(BigDecimal.valueOf(12), 2, BigDecimal.ROUND_HALF_UP)
                //* 期数
                .multiply(BigDecimal.valueOf(sfperiods)).setScale(2, BigDecimal.ROUND_HALF_UP);

        ////利息合计 InterestCount
        BigDecimal InterestCount = new BigDecimal(0.00);
        //还款总额合计      (账期还款金额的合计)
        BigDecimal rePaymentCount = new BigDecimal(0.00);
        //应付租约合计      (总金额)
        BigDecimal payAbleCounts = payAbleCount;
        // 根据一段时间区间，按月份拆分成多个时间段
        List<KeyValueForDate> splitMonth = getSplitMonthForDate(sfdto.getStartDate(), sfdto.getEndDate());
        //收房合同
        TSfContract sfentity = sfContractService.getById(sfdto.getContractId());
        SearchSfLoanDetailMiniResponseDto sfdmini=null;
        // 账期利息 （每月利息）= 利息总和/ 期数
        BigDecimal rateAmount = monthRateAmounts.divide(BigDecimal.valueOf(sfperiods), 2, BigDecimal.ROUND_HALF_UP);
        //计算月租金
        // 账期还款金额（每月账期还款金）= 还款总额合计 / 期数
        BigDecimal repaymentAmount_ = payAbleCounts.divide(BigDecimal.valueOf(sfperiods),2,BigDecimal.ROUND_HALF_UP);
        //还款额+利息
        BigDecimal repaymentAmount = repaymentAmount_.add(rateAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
        //利息合计
        InterestCount = InterestCount.add(monthRateAmounts);
        // 还款总额合计  = 账期还款金额（每月账期还款金）* 期数
        rePaymentCount = repaymentAmount.multiply(BigDecimal.valueOf(sfperiods)).setScale(2, BigDecimal.ROUND_HALF_UP);
        // 循环计算分期详情列表
        int no = 1; //序号
        for (KeyValueForDate v : splitMonth) {
            sfdmini=new SearchSfLoanDetailMiniResponseDto();
            sfdmini.setNo(no);
            // 房产编号
            sfdmini.setRoomCode(sfentity.getHouseId());
            // 房产信息 = 小区名+房产信息
            sfdmini.setRealEstateInfo(sfentity.getPremiseName()+sfentity.getHouseName());
            // 账期利息
            sfdmini.setMonthRateAmount(rateAmount);
            // 月租金(账期还款金额)
            sfdmini.setMonthRepaymentAmount(repaymentAmount);
            // 借款期限(合同开始日)
            sfdmini.setStarLoanday(v.getStartDate());
            // 借款期限(合同结束日)
            sfdmini.setEndLoanday(v.getEndDate());
            spList.add(sfdmini);
            no++;
        }
        // 应付租约合计
        dto.setPayAbleCount(payAbleCounts + "");
        // 还款总额合计
        dto.setRePaymentCount(rePaymentCount + "");
        // 收房贷利息合计
        dto.setInterestCount(InterestCount + "");
        // 一次性服务费
        dto.setSerCharge(serCharge + "");
        //产品id
        dto.setProductId(product.getId());
        //授信额
        dto.setSxAbleCount(sxBalance + "");
        //分期详情列表
        dto.setSfLoan(spList);
        //合同id
        dto.setId(sfdto.getContractId());
        //一次性服务费率
        dto.setServiceFee(sfdto.getServiceFee());
        //利率
        dto.setRate(sfdto.getRate());
        return dto;
    }

    @Override
    public JrProduct selectById(Long productId) {
        return jrProductService.getById(productId);
    }


    /**
     * @deprecated  根据一段时间区间，按月份拆分成多个时间段
     * @Date 2022/4/6 16:50
     **/
    public List<KeyValueForDate> getSplitMonthForDate(Date start, Date end) {
        String startDate = new SimpleDateFormat("yyyy-MM-dd").format(start);
        String endDate = new SimpleDateFormat("yyyy-MM-dd").format(end);
        List<KeyValueForDate> list = null;
        try {
            list = new ArrayList<KeyValueForDate>();
            Date d1 = new SimpleDateFormat("yyyy-MM-dd").parse(startDate);// 定义起始日期
            Date d2 = new SimpleDateFormat("yyyy-MM-dd").parse(endDate);// 定义结束日期
            Calendar dd = Calendar.getInstance();// 定义日期实例
            dd.setTime(d1);// 设置日期起始时间
            Calendar c = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            KeyValueForDate keyValueForDate = null;
            while (dd.getTime().before(d2)) {// 判断是否小于结束日期
                if (sdf.format(dd.getTime()).equals(sdf.format(d1))) {
                    keyValueForDate = new KeyValueForDate();
                    keyValueForDate.setStartDate(sdf.format(dd.getTime()));
                    c.setTime(dd.getTime());
                    c.add(Calendar.MONTH, 1);
                    c.add(Calendar.DATE, -1);
                    keyValueForDate.setEndDate(sdf.format(c.getTime()));
                    list.add(keyValueForDate);
                    dd.setTime(c.getTime());
                } else {
                    c.setTime(dd.getTime());
                    c.add(Calendar.DATE, 1);
                    dd.setTime(c.getTime());
                    keyValueForDate = new KeyValueForDate();
                    keyValueForDate.setStartDate(sdf.format(dd.getTime()));
                    c.setTime(dd.getTime());
                    c.add(Calendar.MONTH, 1);
                    SimpleDateFormat mm = new SimpleDateFormat("MM");
                    SimpleDateFormat yy = new SimpleDateFormat("yyyy");
                    int year = Integer.parseInt(yy.format(c.getTime()));
                    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                        if (mm.format(c.getTime()).equals("02")) {
                        }
                    } else {
                        if (mm.format(c.getTime()).equals("02")) {
                            c.add(Calendar.DATE, 1);
                        }
                    }
                    String checkd1 = sdf.format(c.getTime());
                    String checkd2 = sdf.format(d2.getTime());
                    if (d2.before(c.getTime()) || checkd1.equals(checkd2)) { // 判断是否大于结束日期，是则直接保存结束日期
                        keyValueForDate.setEndDate(sdf.format(d2.getTime()));
                        list.add(keyValueForDate);
                        dd.setTime(c.getTime());
                    } else {// 保存结束日期
                        c.add(Calendar.DATE, -1);
                        keyValueForDate.setEndDate(sdf.format(c.getTime()));
                        list.add(keyValueForDate);
                        dd.setTime(c.getTime());
                    }
                }
            }
        } catch (ParseException e) {
            return null;
        }
        return list;
    }


    public class KeyValueForDate {
        private String startDate;
        private String endDate;

        public String getStartDate() {
            return startDate;
        }

        public void setStartDate(String startDate) {
            this.startDate = startDate;
        }

        public String getEndDate() {
            return endDate;
        }

        public void setEndDate(String endDate) {
            this.endDate = endDate;
        }
    }

}
